package com.example.wlzz.controller;
import com.example.wlzz.constant.RedisConstant;
import com.example.wlzz.dto.*;
import com.example.wlzz.entity.User_;
import com.example.wlzz.entity.mongoEntity.LoveTask;
import com.example.wlzz.entity.sayLove.LoveComment;
import com.example.wlzz.entity.sayLove.LoveSubreview;
import com.example.wlzz.entity.sayLove.LoveWall;
import com.example.wlzz.enums.Del_flagEnum;
import com.example.wlzz.enums.ResultEnum;
import com.example.wlzz.form.SayLoveForm;
import com.example.wlzz.repository.UserRepository;
import com.example.wlzz.repository.mongoRepository.LoveCommentRepository;
import com.example.wlzz.repository.mongoRepository.LoveSubreviewRepository;
import com.example.wlzz.repository.mongoRepository.LoveTaskRepository;
import com.example.wlzz.repository.mongoRepository.LoveWallRepository;
import com.example.wlzz.service.UserInfoService;
import com.example.wlzz.utils.ResultVOUtil;
import com.example.wlzz.vo.CommentPageVO;
import com.example.wlzz.vo.PageVO;
import com.example.wlzz.vo.ResultVO;
import com.mongodb.client.MongoCollection;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/saylove")
@Slf4j
@Api(tags = "表白墙")
@Transactional
public class SayLove {
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private LoveWallRepository loveWallRepository;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private LoveTaskRepository loveTaskRepository;
    @Autowired
    private LoveCommentRepository loveCommentRepository;
    @Autowired
    private LoveSubreviewRepository loveSubreviewRepository;
    @PostMapping("/saveLove")
    @ApiOperation("保存表白（app不需要接入）")
    public ResultVO saveLove(@Valid SayLoveForm sayLoveForm, BindingResult bindingResult,
                             @ApiParam("token") @RequestParam("token") String token){
        if(bindingResult.hasErrors()) {
            return ResultVOUtil.error(ResultEnum.DATA_ERROR.getCode(),ResultEnum.DATA_ERROR.getMessage());
        }
        UserInfoDTO userInfo = (UserInfoDTO)userInfoService.getUserInfo(token).getData();
        if(StringUtils.isEmpty(userInfo.getSchoolName())){
            return ResultVOUtil.error(ResultEnum.SCHOOL_NAME_NULL.getCode(),ResultEnum.SCHOOL_NAME_NULL.getMessage());
        }
        LoveWall loveWall = new LoveWall();
        loveWall.setCreateTime(new Date());
        loveWall.setNiming(Integer.valueOf(sayLoveForm.getNiming()));
        loveWall.setSchool(userInfo.getSchoolName());
        loveWall.setToUsername(sayLoveForm.getToUsername());
        loveWall.setContent(sayLoveForm.getContent());
        loveWall.setUserId(userInfo.getUserId());
        loveWall.setUsername(sayLoveForm.getUsername());
        loveWall.setDelFlag(Del_flagEnum.EXIST.getCode());
        return ResultVOUtil.success(loveWallRepository.save(loveWall));
    }
    @PostMapping("/getLoveWall")
    @ApiOperation("得到表白墙列表")
    public ResultVO getLoveWall(@ApiParam("token凭据") @RequestParam("token") String token,
                                @ApiParam("当前页数(第0页开始)") @RequestParam("page") Integer page,
                                @ApiParam("限制条数") @RequestParam("size") Integer size){
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(page,size,sort);
        Page<LoveWall> loveWallPage = loveWallRepository.findByDelFlag(Del_flagEnum.EXIST.getCode(),request);
        PageVO pageVO = new PageVO();
        pageVO.setCurrentPage(page);
        pageVO.setSize(size);
        pageVO.setDataList(loveWallPage.getContent());
        pageVO.setTotalPage(loveWallPage.getTotalPages());
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        return ResultVOUtil.success(loveWallListToPage(pageVO,user.getUserId()));
    }

    @PostMapping("/commentLoveWall")
    @ApiOperation("主评论表白墙")
    public ResultVO commentLoveWall(@ApiParam("token凭据") @RequestParam("token") String token,
                                @ApiParam("表白墙id") @RequestParam("id") String id,
                                @ApiParam("评论内容") @RequestParam("content") String content){
        LoveWall loveWall  = loveWallRepository.findBy_idAndDelFlag(id,Del_flagEnum.EXIST.getCode());
        if(loveWall==null){
            return ResultVOUtil.error(ResultEnum.LOVEWALL_NO_EXIST.getCode(),ResultEnum.LOVEWALL_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        LoveComment comment = new LoveComment();
        comment.setContent(content);
        comment.setCreateTime(new Date());
        comment.setDelFlag(Del_flagEnum.EXIST.getCode());
        comment.setLoveWallId(id);
        comment.setUserid(user.getUserId());
        return ResultVOUtil.success(loveCommentRepository.save(comment));
    }

    @PostMapping("/subreviewLoveWall")
    @ApiOperation("子评论表白墙")
    public ResultVO subreviewLoveWall(@ApiParam("token凭据") @RequestParam("token") String token,
                                    @ApiParam("评论id") @RequestParam("id") String id,
                                    @ApiParam("评论内容") @RequestParam("content") String content){
        LoveComment loveComment  = loveCommentRepository.findBy_idAndDelFlag(id,Del_flagEnum.EXIST.getCode());
        if(loveComment==null){
            return ResultVOUtil.error(ResultEnum.LOVEWALL_NO_EXIST.getCode(),ResultEnum.LOVEWALL_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        LoveSubreview loveSubreview = new LoveSubreview();
        loveSubreview.setCommentId(loveComment.get_id());
        loveSubreview.setContent(content);
        loveSubreview.setCreateTime(new Date());
        loveSubreview.setDelFlag(Del_flagEnum.EXIST.getCode());
        loveSubreview.setUserid(user.getUserId());
        return ResultVOUtil.success(loveSubreviewRepository.save(loveSubreview));
    }


    @PostMapping("/getLoveWallSubreview")
    @ApiOperation("得到表白墙的子评论")
    public ResultVO getLoveWallSubreview(@ApiParam("token凭据") @RequestParam("token") String token,
                                @ApiParam("表白墙的主评论的id") @RequestParam("commentId") String commentId,
                                @ApiParam("当前页数(第0页开始)") @RequestParam("page") Integer page,
                                @ApiParam("限制条数") @RequestParam("size") Integer size){
        Sort sort = new Sort(Sort.Direction.ASC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(page,size,sort);
        Page<LoveSubreview> loveSubreviewPage = loveSubreviewRepository.findByCommentIdAndDelFlag(commentId,Del_flagEnum.EXIST.getCode(),request);
        CommentPageVO pageVO = new CommentPageVO();
        pageVO.setTotalPage(loveSubreviewPage.getTotalPages());
        pageVO.setSize(size);
        pageVO.setDataList(loveSubreviewPage.getContent());
        pageVO.setCurrentPage(page);
        Long count = loveSubreviewPage.getTotalElements();
        pageVO.setCount(count.intValue());
        return ResultVOUtil.success(pageVO);
    }

    @PostMapping("/getLoveWallComment")
    @ApiOperation("得到表白墙的主评论")
    public ResultVO getLoveWallComment(@ApiParam("token凭据") @RequestParam("token") String token,
                                @ApiParam("表白墙的id") @RequestParam("loveWallId") String loveWallId,
                                @ApiParam("当前页数(第0页开始)") @RequestParam("page") Integer page,
                                @ApiParam("限制条数") @RequestParam("size") Integer size){
        Sort sort = new Sort(Sort.Direction.ASC,"createTime");
        PageRequest request =  PageRequest.of(page,size,sort);
        Page<LoveComment> loveCommentPage = loveCommentRepository.findByLoveWallIdAndDelFlag(loveWallId,Del_flagEnum.EXIST.getCode(),request);
        List<LoveWallCommentDTO> loveWallCommentDTOList = new ArrayList<>();
        for (LoveComment loveComment : loveCommentPage.getContent()) {
            LoveWallCommentDTO loveWallCommentDTO = new LoveWallCommentDTO();
            loveWallCommentDTO.set_id(loveComment.get_id());
            loveWallCommentDTO.setContent(loveComment.getContent());
            loveWallCommentDTO.setCreateTime(loveComment.getCreateTime());
            CommentPageVO subreviewPage =  (CommentPageVO)getLoveWallSubreview(token,loveComment.get_id(),0,5).getData();
            loveWallCommentDTO.setCommentPageVOList(subreviewPage.getDataList());
            loveWallCommentDTO.setSubreviewCount(subreviewPage.getCount());
            loveWallCommentDTOList.add(loveWallCommentDTO);
        }
        PageVO pageVO = new PageVO();
        pageVO.setDataList(loveWallCommentDTOList);
        pageVO.setTotalPage(loveCommentPage.getTotalPages());
        pageVO.setSize(loveCommentPage.getSize());
        pageVO.setCurrentPage(page);
        return ResultVOUtil.success(pageVO);
    }

    public PageVO loveWallListToPage(PageVO pageVO,int userid){
        List<LoveWall> loveWallList = pageVO.getDataList();
        MongoCollection<Document> documentMongoCollection =  mongoTemplate.getCollection("loveTask");
        MongoCollection<Document> commentCollention =  mongoTemplate.getCollection("loveComment");
        List<LoveWallDTO> loveWallDTOList = new ArrayList<>();
        for (LoveWall loveWall : loveWallList) {  //重新封装打包数据
            LoveWallDTO loveWallDTO = new LoveWallDTO();
            BeanUtils.copyProperties(loveWall,loveWallDTO);
            Document document1 = new Document();
            document1.put("taskId",loveWall.get_id());  //这里的taskId代指表白墙的id
            Document document2 = new Document();  //comment的条件
            document2.put("loveWallId",loveWall.get_id());
            document2.put("delFlag",Del_flagEnum.EXIST.getCode());
            Long count =  documentMongoCollection.count(document1);
            loveWallDTO.setLove(count.intValue());
            LoveTask mongoLoveTask = loveTaskRepository.findByTaskIdAndUserid(loveWall.get_id(),userid);
            if(mongoLoveTask!=null){
                loveWallDTO.setLoveFlag(1);
            }else{
                loveWallDTO.setLoveFlag(0);
            }
            Long commentCount =  commentCollention.count(document2);
            loveWallDTO.setCommentCount(commentCount.intValue());
            loveWallDTOList.add(loveWallDTO);
        }
        pageVO.setDataList(loveWallDTOList);
        return pageVO;
    }

    @PostMapping("/myLove")
    @ApiOperation("得到自己发布的表白墙")
    public ResultVO myLove(@ApiParam("token凭据") @RequestParam("token") String token,
                                       @ApiParam("当前页数(第0页开始)") @RequestParam("page") Integer page,
                                       @ApiParam("限制条数") @RequestParam("size") Integer size){
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(page,size,sort);
        Page<LoveWall> loveWallPage = loveWallRepository.findByUserIdAndDelFlag(user.getUserId(),Del_flagEnum.EXIST.getCode(),request);
        PageVO pageVO = new PageVO();
        pageVO.setCurrentPage(page);
        pageVO.setSize(size);
        pageVO.setDataList(loveWallPage.getContent());
        pageVO.setTotalPage(loveWallPage.getTotalPages());
        return ResultVOUtil.success(loveWallListToPage(pageVO,user.getUserId()));
    }
    @PostMapping("/loveToWall")
    @ApiOperation("点赞表白墙")
    public ResultVO loveToWall(@ApiParam("token凭据") @RequestParam("token") String token,
                               @ApiParam("表白墙ID") @RequestParam("id") String id) {
        LoveWall loveWall  = loveWallRepository.findBy_idAndDelFlag(id,Del_flagEnum.EXIST.getCode());
        if(loveWall==null){
            return ResultVOUtil.error(ResultEnum.LOVEWALL_NO_EXIST.getCode(),ResultEnum.LOVEWALL_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        LoveTask islove = loveTaskRepository.findByTaskIdAndUserid(id,user.getUserId());
        if(islove!=null){
            return ResultVOUtil.error(ResultEnum.LOVE_TASK_EXIST.getCode(),ResultEnum.LOVE_TASK_EXIST.getMessage());
        }
        LoveTask loveTask = new LoveTask();
        loveTask.setTaskId(id);
        loveTask.setUserid(user.getUserId());
        loveTaskRepository.save(loveTask);
        return ResultVOUtil.success();
    }
    @PostMapping("/cancel_love")
    @ApiOperation("取消点赞表白墙")
    public ResultVO cancel_love(@ApiParam("token凭据") @RequestParam("token") String token,
                                @ApiParam("表白墙ID") @RequestParam("id") String id) {
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        LoveTask loveTask =  loveTaskRepository.findByTaskIdAndUserid(id,user.getUserId());
        if(loveTask==null){
            return ResultVOUtil.error(ResultEnum.LOVE_NO_EXIST.getCode(),ResultEnum.LOVE_NO_EXIST.getMessage());
        }else{
            loveTaskRepository.delete(loveTask);
            return ResultVOUtil.success();
        }
    }

    @PostMapping("/deleteWall")
    @ApiOperation("删除自己的表白墙")
    public ResultVO deleteWall(@ApiParam("token凭据") @RequestParam("token") String token,
                                @ApiParam("表白墙ID") @RequestParam("id") String id) {
        LoveWall loveWall = loveWallRepository.findBy_idAndDelFlag(id, Del_flagEnum.EXIST.getCode());
        if (loveWall == null) {
            return ResultVOUtil.error(ResultEnum.LOVEWALL_NO_EXIST.getCode(), ResultEnum.LOVEWALL_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        if (loveWall.getUserId() == user.getUserId()) {
                loveWall.setDelFlag(Del_flagEnum.DELETE.getCode());
                loveWallRepository.save(loveWall);
                return ResultVOUtil.success();
        } else {
            return ResultVOUtil.error(ResultEnum.IIIEGAL_ACTION.getCode(), ResultEnum.IIIEGAL_ACTION.getMessage());
        }  }
}
